package com.ai.service.made.impl;

import com.ai.check.CameraCheck;
import com.ai.common.CommonResponse;

import com.ai.common.exception.ServiceException;
import com.ai.entity.made.camera.*;
import com.ai.entity.made.page.CameraPage;
import com.ai.mapper.made.CameraMapper;

import com.ai.service.made.CameraFunctionsService;
import com.ai.service.made.CameraService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Mr.Chen
 * @since 2020-06-17
 */
@Service
public class CameraServiceImpl extends ServiceImpl<CameraMapper, CameraPO> implements CameraService {


    @Resource
    CameraFunctionsService cameraFunctionsService;


    /**
     * 通过ID查询
     *
     * @param cameraBO
     * @return
     */
    @Override
    public CommonResponse oneById(CameraBO cameraBO) {
        CameraPO cameraPO = getById(cameraBO.getId());
        CameraVO cameraVO = CameraVO.convertPOToVO(cameraPO);
        return CommonResponse.ok(cameraVO);
    }

    /**
     * 摄像头状态无法修改
     * 修改信息 state 无法修改，maxNum 无法修改
     * 非空校验
     * currentId，id
     * <p>
     * 修改前准备，下面的非空判断前提是 state 必须>0 ,id  不等于当前被修改 id
     * 如果 nickname 不为空，判断是否重复，重复则返回：nickname 已存在
     * 如果 code 不为空，判断是否重复，重复则返回：code 已存在
     * 如果 ip 不为空，判断是否重复，重复则返回：ip 已存在
     *
     * @param cameraBO
     * @return
     */
    @Override
    public CommonResponse modifyInfo(CameraBO cameraBO) {
        CameraCheck cameraCheck = new CameraCheck();
        if (cameraCheck.isCheckID(cameraBO)) {
            return cameraCheck.resultData;
        }
        CameraPO cameraPO = null;

//        检查摄像头代码是否已经存在
        if (!StringUtils.isEmpty(cameraBO.getCode())) {
            List<CameraPO> list = list(new QueryWrapper<CameraPO>()
                    .eq("code", cameraBO.getCode())
                    .ne("id", cameraBO.getId())
                    .gt("state", 0));
            if (list != null && list.size() > 0) {
                return CommonResponse.error("摄像头代码已存在");
            }
        }

//        检查摄像头名称是否已经存在
        if (!StringUtils.isEmpty(cameraBO.getNickname())) {
            List<CameraPO> list = list(new QueryWrapper<CameraPO>()
                    .eq("nickname", cameraBO.getNickname())
                    .ne("id", cameraBO.getId())
                    .gt("state", 0));
            if (list != null && list.size() > 0) {
                return CommonResponse.error("摄像头名已存在");
            }
        }
        /*if (!StringUtils.isEmpty(cameraBO.getIp())) {
            List<CameraPO> list = list(new QueryWrapper<CameraPO>()
                    .eq("ip", cameraBO.getIp())
                    .ne("id", cameraBO.getId())
                    .gt("state", 0));
            if (list != null && list.size() > 0) {
                return CommonResponse.failResult("摄像头IP已存在");
            }
        }*/
        cameraPO = null;
        cameraPO = cameraBO.convertBOToPO(cameraBO);
        cameraPO.setState(null);
        cameraPO.setMaxNum(null);
        // : 2023-06-07 通知算法
//        cameraFunctionsService.sendFullFunctions();

        if (updateById(cameraPO)) {
            return CommonResponse.ok("修改成功");
        }
        return CommonResponse.error("修改失败");
    }

    /**
     * 添加
     *
     * @param cameraBO
     * @return
     */
    @Override
    @Transactional
    public CommonResponse insert(CameraBO cameraBO) {
//        CameraCheck cameraCheck = new CameraCheck();
//        if (cameraCheck.isAdd(cameraBO)) {
//            return cameraCheck.resultData;
//        }
        CameraPO cameraPO = null;
        if (!StringUtils.isEmpty(cameraBO.getCode())) {
            cameraPO = getOne(new QueryWrapper<CameraPO>()
                    .eq("code", cameraBO.getCode())
                    .gt("state", 0));
            if (cameraPO != null) {
                return CommonResponse.error("摄像头代码已存在");
            }
        }
        if (!StringUtils.isEmpty(cameraBO.getNickname())) {
            cameraPO = getOne(new QueryWrapper<CameraPO>()
                    .eq("nickname", cameraBO.getNickname())
                    .gt("state", 0));
            if (cameraPO != null) {
                return CommonResponse.error("摄像头名已存在");
            }
        }
        if (StringUtils.isEmpty(cameraBO.getServerId()) || cameraBO.getServerId() == 0) {
            return CommonResponse.error("请选择服务器");
        }

        cameraPO = CameraBO.convertBOToPO(cameraBO);
        cameraPO.setState(2);
        cameraPO.setMaxNum(200);

        save(cameraPO);

        // : 2023-06-07  算法接口 ，后续补上
//        cameraFunctionsService.sendFullFunctions();
//        baseSave(cameraBO.getCurrentId(), cameraPO);
        return CommonResponse.ok("添加成功");
    }
/*
    @Transactional
    public void baseSave(int currentId, CameraPO cameraPO) {
        boolean b = save(cameraPO);
        if (b) {
            List<FunctionPO> list = functionService.list(new QueryWrapper<FunctionPO>().gt("state", 0));
            list.forEach(functionPO -> {
                CameraFunctionPO cameraFunctionPO = new CameraFunctionPO();
                cameraFunctionPO.setCameraId(cameraPO.getId());
                cameraFunctionPO.setFunctionId(functionPO.getId());
                cameraFunctionPO.setSpots(functionPO.getSpots());
                cameraFunctionService.save(cameraFunctionPO);
            });
        } else {
            throw new ServiceException("添加失败");
        }
    }*/

    /**
     * 删除
     *
     * @param cameraBO
     * @return
     */
    @Override
    public CommonResponse delete(CameraBO cameraBO) {
        CameraCheck cameraCheck = new CameraCheck();
        if (cameraCheck.isCheckID(cameraBO)) {
            return cameraCheck.resultData;
        }
        removeById(cameraBO.getId());

        // : 2023-06-07  算法接口 ，后续补上
//        cameraFunctionsService.sendFullFunctions();

        return CommonResponse.ok("删除成功");
    }

    /**
     * 查询开启摄像头列表
     *
     * @param cameraBO
     * @return
     */
    @Override
    public CommonResponse selectByOpen(CameraBO cameraBO) {
        cameraBO.setState(1);
        List<CameraPO> cameraPOList = list(new QueryWrapper<CameraPO>()
                .like((!StringUtils.isEmpty(cameraBO.getNickname())), "nickname", cameraBO.getNickname())
                .like((!StringUtils.isEmpty(cameraBO.getCode())), "code", cameraBO.getCode())
                .eq("state", 1));
        List<CameraVO> cameraVOList = new ArrayList<>();
        cameraPOList.forEach(cameraPO -> {
            CameraVO cameraVO = new CameraVO();
            BeanUtils.copyProperties(cameraPO, cameraVO);
            cameraVOList.add(cameraVO);
        });
        return CommonResponse.ok(cameraVOList);
    }

    /**
     * 分页查询，列表查询除密码以外的所有用户信息
     *
     * @param page
     * @return
     */
    @Override
    public CommonResponse selectByPage(CameraPage page) {
        QueryWrapper<CameraPO> queryWrapper = new QueryWrapper<>();
//        queryWrapper.orderByDesc("camera.id");
        queryWrapper = page.getQuery(queryWrapper);
        IPage<CameraVO> voIPage = baseMapper.cameraList(page, queryWrapper);
        return CommonResponse.ok(voIPage);
    }

    /**
     * 批量删除
     *
     * @param cameraIdBO
     * @return
     */
    @Override
    public CommonResponse bulkDelete(CameraIdBO cameraIdBO) {
        CameraCheck cameraCheck = new CameraCheck();
        if (cameraCheck.isCurrentID(cameraIdBO.getCurrentId())) {
            return cameraCheck.resultData;
        }

        List<Integer> ids = new ArrayList<>();
        if (cameraIdBO.getIds() != null && cameraIdBO.getIds().size() > 0) {
            ids = byIds(cameraIdBO.getIds());
        }
        if (ids.size() <= 0 && cameraIdBO.getCodes() != null && cameraIdBO.getCodes().size() > 0) {
            ids = byCodes(cameraIdBO.getCodes());
        }
        if (ids.size() <= 0) {
            return CommonResponse.error("请选择有效设备");
        }

        bulkDelete(ids);
        return CommonResponse.ok("移除摄像头成功");
    }

    /**
     * 查询人员流动摄像头列表
     *
     * @return
     */
    @Override
    public CommonResponse listByPersonFlow(CameraPage page) {
        IPage<CameraPO> iPage = baseMapper.listByPersonFlow(page,
                new QueryWrapper<CameraPO>()
                        .eq("functions.type", 2020)
                        .eq("camera.state", 1)
                        .eq("camera_function.state", 1));
        IPage<CameraVO> voIPage = iPage.convert(CameraVO::convertPOToVO);
        return CommonResponse.ok(voIPage);
    }

    @Transactional
    public void bulkDelete(List<Integer> ids) {
        try {
            ids.forEach(id -> {
                CameraPO cameraPO = new CameraPO();
                cameraPO.setState(-1);
                update(cameraPO, new QueryWrapper<CameraPO>().eq("id", id));
            });
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("数据库异常");
        }
    }

    @Override
    public List<Integer> openCameraList() {
        List<Integer> ids = baseMapper.openCameraIdList();
        if (ids.size() <= 0) {
            return null;
        }
        return ids;
    }

    @Override
    public List<Integer> pageCameraIdList(int start, int size) {
        List<Integer> ids = baseMapper.pageCameraIdList(start, size);
        if (ids.size() <= 0) {
            return null;
        }
        return ids;
    }

    private List<Integer> byIds(List<Integer> cameraIds) {
        List<Integer> ids = new ArrayList<>();
        cameraIds.forEach(id -> {
            if (getById(id) != null)
                ids.add(id);
        });
        return ids;
    }

    private List<Integer> byCodes(List<String> codes) {
        List<Integer> ids = new ArrayList<>();
        codes.forEach(code -> {
            CameraPO cameraPO = getOne(new QueryWrapper<CameraPO>().eq("code", code));
            if (cameraPO != null)
                ids.add(cameraPO.getId());
        });
        return ids;
    }

    @Override
    public CameraPO getByCode(String code) {
        return getOne(new QueryWrapper<CameraPO>().eq("code", code));
    }

    @Override
    public CommonResponse selectByFunctionType(final int type) {
        List<CameraPO> cameraPOIPage = baseMapper.selectByFunctionType(type);
        return CommonResponse.ok(cameraPOIPage);
    }

    /**
     *
     * @param cameraIdBO
     * @return
     */
    @Override
    public CameraPO getCameraOn(CameraIdBO cameraIdBO) {
        CameraPO cameraPO = null;


        Integer id = cameraIdBO.getId();
        if (id != null && id != 0) {
            cameraPO = getById(id);
        }
        String code = cameraIdBO.getCode();

//        如果摄像头id为0，且摄像头的代号不为空，就使用代号去查找摄像头，但是如果摄像头代号为空，又能代表什么呢
        if (id == 0 && !StringUtils.isEmpty(code)) {
            cameraPO = getOne(new QueryWrapper<CameraPO>().eq("code", code));
        }
        return cameraPO;
    }
}
